SPDX-FileCopyrightText: 2022 Lina El Ouali & Marin Georges SPDX-FileCopyrightText: 2024 AlICe laboratory https://alicelab.be
SPDX-License-Identifier: GPL-3.0-or-later
script written in blender 3.3.0 hash 0759f671cclf on windows 11 Giant Steps John Coltrane Martin Georges & Lina el Ouali 2022-2023
LIBRAIRIES
import bpy
import random
import mathCLEAN
Delete ALL objects and related meshes from Blender file.
The file is not saved or reopened in the process.
Select all objects and delete them from the scene.
    def clean():
    bpy.ops.object.select_all(action="SELECT")
    bpy.ops.object.delete()
    bpy.ops.outliner.orphans_purge()
clean()radius_step = 10
current_radius = 10
number_shapes = 12
z_step = 12
for i in range(1, number_shapes):-------- STEP 1: CREATING A COORDONATES NETWORK --------# Circle of fifths# Cuts the circle of fifths into 12 notes to extract coordonates, prepares for the generative figures Adds the center of the circle as a coordonate
    current_radius = i * radius_step
    bpy.ops.mesh.primitive_circle_add(
        vertices=12, scale=(1, 1, 1), radius=current_radius, location=(0, 0, 0)
    )
    coord = [
        tuple(ver.co) for ver in list(bpy.context.selected_objects[0].data.vertices)
    ]
    notes = ["C", "F", "Bb", "Eb", "Ab", "Db", "Gb", "B", "E", "A", "D", "G"]
    keys_dict = {}    for co, note in zip(coord, notes):
        keys_dict[note] = co
    keys_dict["O"] = (0, 0, 0)
    print(keys_dict)-------- STEP 2: SET THE 12 DIFFERENT CHORDS EXISTING IN THE CIRCLE --------# Creation of a verticles network# Creation of the 12 different shapes according to the chord played. Note: the different shape is refered to as [cord]Vert.
    cVert = [keys_dict["C"], keys_dict["Eb"], keys_dict["Ab"], keys_dict["D"]]
    fVert = [keys_dict["C"], keys_dict["F"], keys_dict["Ab"], keys_dict["O"]]
    bbVert = [keys_dict["D"], keys_dict["F"], keys_dict["Bb"], keys_dict["Ab"]]
    ebVert = [keys_dict["D"], keys_dict["G"], keys_dict["Bb"], keys_dict["Eb"]]
    abVert = [keys_dict["A"], keys_dict["Eb"], keys_dict["Ab"], keys_dict["Gb"]]
    dbVert = [
        keys_dict["O"],
        keys_dict["Ab"],
        keys_dict["Db"],
        keys_dict["B"],
        keys_dict["E"],
    ]
    gbVert = [keys_dict["E"], keys_dict["Bb"], keys_dict["Db"], keys_dict["Gb"]]
    bVert = [
        keys_dict["O"],
        keys_dict["Bb"],
        keys_dict["Eb"],
        keys_dict["Gb"],
        keys_dict["B"],
    ]
    eVert = [
        keys_dict["E"],
        keys_dict["D"],
        keys_dict["G"],
        keys_dict["O"],
        keys_dict["Gb"],
    ]
    aVert = [
        keys_dict["E"],
        keys_dict["A"],
        keys_dict["G"],
        keys_dict["C"],
        keys_dict["O"],
    ]
    dVert = [keys_dict["Gb"], keys_dict["A"], keys_dict["D"], keys_dict["C"]]
    gVert = [keys_dict["O"], keys_dict["Gb"], keys_dict["D"], keys_dict["G"]]list of the shapes
    myFigures = [
        cVert,
        fVert,
        bbVert,
        ebVert,
        abVert,
        dbVert,
        gbVert,
        bVert,
        eVert,
        aVert,
        dVert,
        gVert,
    ]-------- STEP 3: LISTS THE ALGORITHM CHOOSES FROM--------# Establishment of different sequences of the introduction part
-INTROS-#
    intro1 = [
        abVert,
        ebVert,
        dVert,
        gbVert,
        bVert,
        bbVert,
        dbVert,
        eVert,
        aVert,
        gVert,
        fVert,
        cVert,
    ]
    intro2 = [
        fVert,
        abVert,
        ebVert,
        gbVert,
        aVert,
        bbVert,
        gVert,
        dVert,
        dbVert,
        cVert,
        eVert,
        bVert,
    ]
    intro3 = [
        dVert,
        bbVert,
        aVert,
        cVert,
        abVert,
        gbVert,
        gVert,
        fVert,
        eVert,
        bVert,
        ebVert,
        dbVert,
    ]
    intro4 = [
        gVert,
        fVert,
        dbVert,
        aVert,
        abVert,
        bVert,
        bbVert,
        cVert,
        dVert,
        gbVert,
        ebVert,
        eVert,
    ]Choosing an intro Establishment of different sequences of the solo part
    Intros = [intro1, intro2, intro3, intro4]
    myIntro = random.choice(Intros)
    print(myIntro)    solo1 = [
        gVert,
        cVert,
        aVert,
        bbVert,
        fVert,
        dVert,
        bVert,
        ebVert,
        gbVert,
        eVert,
        dbVert,
        abVert,
    ]
    solo2 = [
        cVert,
        fVert,
        bbVert,
        gVert,
        gbVert,
        dbVert,
        ebVert,
        eVert,
        bVert,
        aVert,
        abVert,
        dVert,
    ]
    solo3 = [
        dVert,
        bVert,
        ebVert,
        fVert,
        gVert,
        dbVert,
        aVert,
        eVert,
        abVert,
        bbVert,
        gbVert,
        cVert,
    ]
    solo4 = [
        bbVert,
        dbVert,
        gVert,
        abVert,
        dVert,
        gVert,
        abVert,
        dVert,
        cVert,
        fVert,
        aVert,
        gbVert,
    ]choosing a solo
    Solos = [solo1, solo2, solo3, solo4]
    mySolo = random.choice(Solos)
    print(mySolo)-------- STEP 1: PREPARING THE PARAMETERS --------# ----VARIABLES
    radius_step = 10
    current_radius = 10
    z_step = 12----FACES Defining the number of faces as the polygons have different numbers of edges
    myFacesFour = [(0, 1, 2, 3)]
    myFacesFive = [(0, 1, 2, 3, 4)]-------- STEP 2: CREATE A FACE FOR THE INTRO --------#
    for note in range(0, 1):
        myVerticles = myIntro[note]
        if len(myIntro[note]) == 4:
            myFaces = myFacesFour
        else:
            myFaces = myFacesFive
            print(myFaces)creation of the mesh and the object
        myMesh = bpy.data.meshes.new("polyMesh1")
        myObject = bpy.data.objects.new("poly1", myMesh)link object to collection
        myCollection = bpy.context.collection
        myCollection.objects.link(myObject)
        myMesh.from_pydata(myVerticles, [], myFaces)rotate mesh around the y axis
        degrees = -90
        radians = math.radians(degrees)
        myObject.rotation_euler.y = radiansrotate mesh around the z axis
        degrees = z_step * i
        radians = math.radians(degrees)
        myObject.rotation_euler.z = radiansrotate mesh around the y axis
        degrees = 50
        radians = math.radians(degrees)
        myObject.rotation_euler.x = radiansconvert mesh into a curve
        bpy.ops.object.convert(target="CURVE")-------- STEP 1: PREPARING THE PARAMETERS --------# ----VARIABLES
radius_step = 10
current_radius = 10
z_step = 10----FACES
myFacesFour = [(0, 1, 2, 3)]
myFacesFive = [(0, 1, 2, 3, 4)]-------- STEP 2: CREATE THE FACES --------# ----VARIABLES
for note in range(0, 11):SHORTCUT
    myVerticles2 = mySolo[note]
    if len(mySolo[note]) == 4:
        myFaces = myFacesFour
    else:
        myFaces = myFacesFive
        print(myFaces)creation of the mesh and the object
    myMesh2 = bpy.data.meshes.new("polyMesh2")
    myObject2 = bpy.data.objects.new("poly2", myMesh2)link object to collection
    myCollection = bpy.context.collection
    myCollection.objects.link(myObject2)fill the mesh with the verticles information (position of verticles & connection to make face)
    myMesh2.from_pydata(myVerticles2, [], myFaces)rotations
    myObject2.rotation_euler.y = math.radians(note * 30)
    current_radius = note * radius_step
    degrees = -30
    radians = math.radians(degrees)
    myObject2.rotation_euler.x = radians
    degrees = z_step * note
    radians = math.radians(degrees)
    myObject2.rotation_euler.z = radiansall_objects = list(bpy.data.objects)check if objects are named poly
all_poly_objects = []
for obj in all_objects:
    if "poly2" in obj.name:add polys to new list
        all_poly_objects.append(obj)add and apply SOLIDIFY modifier to shapes
bpy.ops.object.select_all(action="DESELECT")
for poly in all_poly_objects:Apply modifier to selected object
    poly.select_set(True)  # selected object
    bpy.context.view_layer.objects.active = poly
    bpy.ops.object.modifier_add(type="SOLIDIFY")
    bpy.context.object.modifiers["Solidify"].thickness = 4
    bpy.ops.object.modifier_apply(modifier="Solidify")
    poly.select_set(False)check if objects are named poly
all_poly_objects = []
for obj in all_objects:
    if "poly1" in obj.name:add polys to new list
        all_poly_objects.append(obj)add and apply SOLIDIFY modifier to shapes
bpy.ops.object.select_all(action="DESELECT")
for poly in all_poly_objects:Apply modifier to selected object
    poly.select_set(True)  # selected object
    bpy.context.view_layer.objects.active = poly
    bpy.ops.object.modifier_add(type="CURVE")
    bpy.ops.object.convert(target="CURVE")
    bpy.context.object.data.bevel_depth = 2shade smooth
    bpy.ops.object.shade_smooth()